import tlv
from socket import *
import struct
from gtalk_client import *
import gtalk_client
from SIMPCore_pb2 import *
import thread
from time import sleep



eTLV_t_HEADER = 0
eTLV_t_FUNCTION_TYPE = 1


eFunT_Register = 10
eFunT_Login = 11
eFunT_Logout = 12
eFunT_AddFriend = 13
eFunT_DelFriend = 14
eFunT_SingleChat = 15
eFunT_UpdateUserStatus = 16
eFunT_BroadcastUserStatus = 17
eFunT_QueryUserStatus = 18
eFunT_FetchUserInfo = 19
eFunT_UpdateUserInfo = 20
eFunT_GetAllFriend = 21
eFunT_GetOnlineFriend = 22
eFunT_Ping = 23
eFunT_Redirect = 24
eFunT_SysPush = 25


eVarT_MSG_Register_Req = 26
eVarT_MSG_Register_Rsp = 27
eVarT_MSG_Login_Req = 28
eVarT_MSG_Login_Rsp = 29
eVarT_MSG_Logout_Req = 30
eVarT_MSG_Logout_Rsp = 31
eVarT_MSG_AddFriend_Req = 32
eVarT_MSG_AddFriend_Rsp = 33
eVarT_MSG_DelFriend_Req = 34
eVarT_MSG_DelFriend_Rsp = 35
eVarT_MSG_SingleChat_Req = 36
eVarT_MSG_SingleChat_Rsp = 37
eVarT_MSG_UpdateUserStatus_Req = 38
eVarT_MSG_UpdateUserStatus_Rsp = 39
eVarT_MSG_BroadcastUserStatus_Req = 40
eVarT_MSG_BroadcastUserStatus_Rsp = 41
eVarT_MSG_QueryUserStatus_Req = 42
eVarT_MSG_QueryUserStatus_Rsp = 43
eVarT_MSG_FetchUserInfo_Req = 44
eVarT_MSG_FetchUserInfo_Rsp = 45
eVarT_MSG_UpdateUserInfo_Req = 46
eVarT_MSG_UpdateUserInfo_Rsp = 47
eVarT_MSG_GetAllFriend_Req = 48
eVarT_MSG_GetAllFriend_Rsp = 49
eVarT_MSG_GetOnlineFriend_Req = 50
eVarT_MSG_GetOnlineFriend_Rsp = 51
eVarT_MSG_Ping_Req = 52
eVarT_MSG_Ping_Rsp = 53
eVarT_MSG_Redirect_Req = 54
eVarT_MSG_Redirect_Rsp = 55
eVarT_MSG_SysPush_Req = 56
eVarT_MSG_SysPush_Rsp = 57


HOST=''
PORT=30001
ADDR=(HOST,PORT)
BUF_SIZE=4096

class RPCServer:
	'''
		rpcserver.
	'''

    

	def run(self):
		server = socket(AF_INET, SOCK_STREAM, 0);
		server.bind(ADDR);
		server.listen(20);

		while True:
			print 'waiting for connections...'
			client = RPCClient();
			client.m_ClientSocket, client.m_ClientAddr = server.accept();
			
			print 'connected from ', client.m_ClientAddr
			client.run();
			client.__del__();



class RPCClient:
        '''
        accept socket client
        '''
        
	def __init__(self):
		self.m_XMPPClient = XMPPClient();
		self.m_ClientSocket = None;
		self.m_ClientAddr = None;
		self.m_pOnAgentDataRecievedProcessHandler = None;
		self.m_pOnAgentDataRecievedProcessHandler = self.OnAgentDataRecievedProcessHandler;
		pass

	def __del__(self):
		self.m_XMPPClient.__del__();
		pass

	def run(self):
#self.m_XMPPClient.g_threadRecieveCallBack = self.ThreadOnChatMessageRecieved;
		while True:
			try:
				data = self.m_ClientSocket.recv(BUF_SIZE);
			except:
				print 'recv error'
				break;
				
			if not data:
				print 'disconnected.'
				break;

			if self.m_pOnAgentDataRecievedProcessHandler:
				print 'm_pOnAgentDataRecievedProcessHandler is ture'
				try:
					self.m_pOnAgentDataRecievedProcessHandler(data, self.send);
				except Exception, e:
					print '======>m_pOnAgentDataRecievedProcessHandler error: ', e
					sleep(1);
				
				
	def send(self,buf):
		self.m_ClientSocket.send(buf);

	def ThreadOnChatMessageRecieved(self):
		print '============>starting recieving thread...'
		try:
			sleep(2)
			self.m_XMPPClient.m_xmppclient.RegisterHandler('message', self.OnChatMessageRecieved);
		except:
			print 'could not RegisterHandler, reRegister========'
#return self.ThreadOnChatMessageRecieved();

		while True:
			try:
				if self.m_XMPPClient.m_xmppclient.Process(1000) == None:
					print 'Lost Connection.'
					break;
			except Exception, e:
				print '====================>>>>>>>>>exception....',e
				sleep(2);



# TODO: mutex, lock, sycn thread
	def OnChatMessageRecieved(self, cnx, msg):
		try:
			print '================OnChatMessageRecieved'
			req = MSG_SingleChat_Req();
	
			req.srcuid=msg.getFrom().getStripped();
			req.dstuid=msg.getTo().getStripped();
			req.content=msg.getBody();

			buf = req.SerializeToString();

			buf_out = "";
			offset_out = 0;
			buf_out, offset_out=tlv.tlv_add(buf_out, offset_out, eTLV_t_HEADER, 4, -100);
			buf_out, offset_out=tlv.tlv_add(buf_out, offset_out, eVarT_MSG_SingleChat_Req, len(buf), buf);
			self.send(buf_out);
		except Exception, e:
			print '=======================>>>>>exception in OnChat..',e
			sleep(5);
        


	
	def OnAgentDataRecievedProcessHandler(self, buf, pfunc_send_cb):
		buf_out = buf[0:12];
		offset_out = 12;
		vlen, functionType = tlv.tlv_get(buf, eTLV_t_FUNCTION_TYPE);
		functionType = struct.unpack('i',functionType)[0];

		print 'functionType=', functionType, 'buf_len=', len(buf)


		if (functionType == eFunT_Login):
			reqbuf = tlv.tlv_get(buf, eVarT_MSG_Login_Req)[1];
			req = MSG_Login_Req();
			req.ParseFromString(reqbuf);
			print "user info=", req.uid, req.password
			rsp = self.m_XMPPClient.Login(req);
			rsp_buf = rsp.SerializeToString();
			buf_out, offset_out=tlv.tlv_add(buf_out, offset_out, eVarT_MSG_Login_Rsp, len(rsp_buf), rsp_buf);


		if (functionType == eFunT_GetAllFriend):
			reqbuf = tlv.tlv_get(buf, eVarT_MSG_GetAllFriend_Req)[1];
			req = MSG_GetAllFriend_Req();
			req.ParseFromString(reqbuf);

			rsp = self.m_XMPPClient.GetAllFriend(req);

			rsp_buf = rsp.SerializeToString();
			buf_out, offset_out=tlv.tlv_add(buf_out, offset_out, eVarT_MSG_GetAllFriend_Rsp, len(rsp_buf), rsp_buf);

		if (functionType == eFunT_SingleChat):
			reqbuf = tlv.tlv_get(buf, eVarT_MSG_SingleChat_Req)[1];
			req = MSG_SingleChat_Req();
			req.ParseFromString(reqbuf);

			rsp = self.m_XMPPClient.SingleChat(req);

			rsp_buf = rsp.SerializeToString();
			buf_out, offset_out=tlv.tlv_add(buf_out, offset_out, eVarT_MSG_SingleChat_Rsp, len(rsp_buf), rsp_buf);

		pfunc_send_cb(buf_out);
		print 'rsp buf len =', offset_out
		if (functionType == eFunT_Login):
#sleep(2);
			thread.start_new_thread(self.ThreadOnChatMessageRecieved,());
		
	
    





server = RPCServer();
server.run();
